import 'dart:async';
import 'dart:io';

import 'package:audio_session/audio_session.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:flutter_sound/public/flutter_sound_player.dart';
import 'package:flutter_sound/public/flutter_sound_recorder.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

class LYRecorderManager {
  LYRecorderManager._internal();
  static final LYRecorderManager _instance = LYRecorderManager._internal();
  static LYRecorderManager get share {
    return _instance;
  }

  FlutterSoundRecorder recorderModule = FlutterSoundRecorder();
  FlutterSoundPlayer playerModule = FlutterSoundPlayer();
  final double _maxLength = 30;
  StreamSubscription? _recorderSubscription;
  StreamSubscription? _playerSubscription;
  int seconds = 0;
  String? fileName;

  Future<void> init() async {
    //开启录音
    await recorderModule.openRecorder();
    //设置订阅计时器
    await recorderModule
        .setSubscriptionDuration(const Duration(milliseconds: 10));
    //初始化日期插件
    await initializeDateFormatting();

    await playerModule.closePlayer();
    await playerModule.openPlayer();
    await playerModule
        .setSubscriptionDuration(const Duration(milliseconds: 10));
//这块是设置音频，暂时没用到可以不用设置
    final session = await AudioSession.instance;
    await session.configure(AudioSessionConfiguration(
      avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
      avAudioSessionCategoryOptions:
          AVAudioSessionCategoryOptions.allowBluetooth |
              AVAudioSessionCategoryOptions.defaultToSpeaker,
      avAudioSessionMode: AVAudioSessionMode.spokenAudio,
      avAudioSessionRouteSharingPolicy:
          AVAudioSessionRouteSharingPolicy.defaultPolicy,
      avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
      androidAudioAttributes: const AndroidAudioAttributes(
        contentType: AndroidAudioContentType.speech,
        flags: AndroidAudioFlags.none,
        usage: AndroidAudioUsage.voiceCommunication,
      ),
      androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
      androidWillPauseWhenDucked: true,
    ));
  }

  Future<bool> getPermissionStatus() async {
    Permission permission = Permission.microphone;
    //granted 通过，denied 被拒绝，permanentlyDenied 拒绝且不在提示
    PermissionStatus status = await permission.status;
    if (status.isGranted) {
      return true;
    } else if (status.isDenied) {
      requestPermission(permission);
    } else if (status.isPermanentlyDenied) {
      openAppSettings();
    } else if (status.isRestricted) {
      requestPermission(permission);
    } else {}
    return false;
  }

  ///申请权限
  void requestPermission(Permission permission) async {
    PermissionStatus status = await permission.request();
    if (status.isPermanentlyDenied) {
      openAppSettings();
    }
  }

  /// 开始录音
  void startRecorder() async {
    seconds = 0;
    try {
      //获取麦克风权限
      final canRecord = await getPermissionStatus();
      if (canRecord) {
        return;
      }

      await _recorderSubscription!.cancel();
      _recorderSubscription = recorderModule.onProgress!.listen((e) {
        var date = DateTime.fromMillisecondsSinceEpoch(
            e.duration.inMilliseconds,
            isUtc: true);
        //设置了最大录音时长
        seconds = date.second;
        if (date.second >= _maxLength) {
          stopRecorder();
          return;
        }
        // setState(() {
        //   //更新录音时长
        //   _recordText = txt.substring(1, 5);
        // });
      });
      //用户允许使用麦克风之后开始录音
      Directory applicationDir = await getApplicationDocumentsDirectory();
      bool isDirExist =
          await Directory("${applicationDir.path}/voices").exists();
      if (!isDirExist) Directory("${applicationDir.path}/voices").create();
      var time = DateTime.now().millisecondsSinceEpoch;
      fileName = "$time${ext[Codec.aacADTS.index]}";

      String path = '${applicationDir.path}/voices/$fileName';
      //这里我录制的是aac格式的，还有其他格式
      await recorderModule.startRecorder(
        toFile: path,
        codec: Codec.aacADTS,
        bitRate: 8000,
        numChannels: 1,
        sampleRate: 8000,
      );

      /// 监听录音

      // setState(() {
      //   //更新录音状态和录音文件路径
      //   _state = RecordPlayState.recording;
      //   _path = path;
      // });
    } catch (err) {
      debugPrint('==startRecorder=err===$err');
      // setState(() {
      //   _stopRecorder();
      //   _state = RecordPlayState.record;
      //   _cancelRecorderSubscriptions();
      // });
    }
  }

  /// 结束录音
  Future<String?> stopRecorder() async {
    try {
      final path = await recorderModule.stopRecorder();
      _cancelRecorderSubscriptions();
      debugPrint('==stopRecorder=path===$path');
      return path;
    } catch (err) {
      debugPrint('==stopRecorder=err===$err');
    }
    return null;
    // setState(() {
    //   _state = RecordPlayState.record;
    // });
  }

  // ///销毁录音
  // void dispose() {
  //   super.dispose();
  //   _cancelRecorderSubscriptions();
  //   _releaseFlauto();
  // }
  /// 取消录音监听
  void _cancelRecorderSubscriptions() {
    if (_recorderSubscription != null) {
      _recorderSubscription!.cancel();
      _recorderSubscription = null;
    }
  }

  /// 释放录音
  Future<void> releaseRecorder() async {
    try {
      await recorderModule.closeRecorder();
    } catch (e) {}
  }

  /// 判断文件是否存在
  Future<bool> _fileExists(String path) async {
    return await File(path).exists();
  }

  ///开始播放，这里做了一个播放状态的回调
  void startPlayer(String path, Function(PlayerState) callBack) async {
    try {
      if (path.contains('http')) {
        await playerModule.startPlayer(
            fromURI: path,
            codec: Codec.mp3,
            sampleRate: 44000,
            whenFinished: () {
              stopPlayer();
              callBack(PlayerState.isStopped);
            });
      } else {
        final isExist = await _fileExists(path);
        //判断文件是否存在
        if (isExist) {
          if (playerModule.isPlaying) {
            playerModule.stopPlayer();
          }
          await playerModule.startPlayer(
              fromURI: path,
              codec: Codec.aacADTS,
              sampleRate: 44000,
              whenFinished: () {
                stopPlayer();
                callBack(PlayerState.isStopped);
              });
        } else {
          callBack(PlayerState.isStopped);
          return;
        }
      }
      // //监听播放进度
      _playerSubscription = playerModule.onProgress!.listen((e) {
        if (e.duration <= e.position) {
          callBack(PlayerState.isStopped);
        }
      });
    } catch (err) {
      callBack(PlayerState.isPlaying);
      debugPrint("$err");
    }
  }

  /// 结束播放
  Future<void> stopPlayer() async {
    try {
      await playerModule.stopPlayer();
      cancelPlayerSubscriptions();
    } catch (err) {}
  }

  /// 取消播放监听
  void cancelPlayerSubscriptions() {
    if (_playerSubscription != null) {
      _playerSubscription!.cancel();
      _playerSubscription = null;
    }
  }

  ///获取播放状态
  Future<PlayerState> getPlayState() async {
    return await playerModule.getPlayerState();
  }

  /// 释放播放器
  void releasePlayer() async {
    try {
      await playerModule.closePlayer();
    } catch (e) {
      debugPrint('$e');
    }
  }
}
